% PTime 每个工件每道工序操作时间矩阵
% Scheme是染色体生产的调度工序（只有此矩阵行是工序）
% BginTime 每个工件每道工序开始工作的时间矩阵
% Ddate  每个工件的交付日期
% PNumber工件
% MNumber工序 ,Mspan,BginTime,Scheme
function [TCost,Mspan,Scheme,BginTime]=my_cal(PTime,Chrom)
[PNumber,MNumber] = size(PTime);
%%%%%%%%%%%%%%%%%%%%%%%%%输入交付时间数据
Ddate=[72 72 72 70 70 72 72 72 72 70 70 72 70]*2;


%%初始化完成时间矩阵
Mspan=zeros(PNumber,MNumber); %用矩阵存储每个工件每道工序的完成时间，初始赋值为零，公式中的C(j,Nk)
BginTime=zeros(PNumber,MNumber);
D=zeros(PNumber,MNumber);
Scheme=zeros(MNumber,PNumber);

     %%%%%%%%%%%%%%%%%%%%%将染色体生产调度工序
     BScheme=zeros(MNumber,PNumber);
    for i=1:MNumber
       BScheme(i,:)=Chrom((i-1)*PNumber+1:i*PNumber); %存放染色体各层级的随机数，每层为矩阵的一行。
    end 
    [ShemeTemp,Scheme]=sort(BScheme,2);%将BforeScheme矩阵按行升序排列，并将原来的下标（即工件）返回给Scheme矩阵，即各工序工件加工顺序

for k=1:MNumber
  switch k
 %%%%%%%%%%%%%%第一道工序的完成时间
      case 1
          for i=1:PNumber
                if i==1     %该工序之前没有工序，单独讨论
                j=Scheme(k,1);
                BginTime(j,k)=0;
                else
                j=Scheme(k,i); %当前工件，Scheme是染色体生产的调度工序
                Previous_j=Scheme(k,i-1); %该工序中的前一个工件
                BginTime(j,k)=Mspan(Previous_j,k);
                end
                Mspan(j,k)=BginTime(j,k)+PTime(j,k);
                D(j,k)=fix(Mspan(j,k)/24);
                if Mspan(j,k)>(24*D(j,k)+10) %Hw=10
                  Mspan(j,k)=Mspan(j,k)+14; %HN=14 ???????
                end
          end

%%%%%%%%%%%%%%%%%%%%第4道工序的完成时间 %浇筑阶段
      case 4 
          for i=1:PNumber
                if i==1     
                 j=Scheme(k,1);
                 BginTime(j,k)=Mspan(j,k-1);
                else
                 j=Scheme(k,i); %当前工件，Scheme是染色体生产的调度工序
                 Previous_j=Scheme(k,i-1); %该工序中的前一个工件
                   if Mspan(Previous_j,k)>Mspan(j,k-1)
                      BginTime(j,k)=Mspan(Previous_j,k);
                   else
                       BginTime(j,k)=Mspan(j,k-1);
                   end
                end
            Mspan(j,k)=BginTime(j,k)+PTime(j,k);% 此条件判断开始时间
            D(j,k)=fix(Mspan(j,k)/24);
                 if Mspan(j,k)>(24*D+10+4) %Hw=10
                    Mspan(j,k)=24*D(j,k)+24+PTime(j,k); 
                    BginTime(j,k)=24*D(j,k)+24; %浇筑阶段工序不可中断，第二天才开始工作，开始时间进行修正
                  end
          end
    
    
    %%%%%%%%%%%%%%%%%%%%第5道工序的完成时间，养护阶段
      case 5 
             a =  floor(PNumber / 3);
         
             for i = 1:a
                 if i == 1
                     j1 = Scheme(k,1);
                     j2 = Scheme(k,2);
                     j3 = Scheme(k,3);
                      
                     temp = max([Mspan(j1,k-1),Mspan(j2,k-1),Mspan(j3,k-1)]);
                     BginTime(j1,k) = temp;
                     BginTime(j2,k) = temp;
                     BginTime(j3,k) = temp;
                     temp_2 = max([PTime(j1,k),PTime(j2,k),PTime(j3,k)]);
                     
    
    
                     Mspan(j1,k) = temp_2 + temp;
                     Mspan(j2,k) = temp_2 + temp;
                     Mspan(j3,k) = temp_2 + temp;
                 else
                     j1 = Scheme(k,3*i-2);
                     j2 = Scheme(k,3*i-1);
                     j3 = Scheme(k,3*i);
                     temp = max([Mspan(j1,k-1) Mspan(j2,k-1) Mspan(j3,k-1)]);
                     Previous_j=Scheme(k,3*i-3);
                     if Mspan(Previous_j,k)>temp
                          BginTime(j1,k)=Mspan(Previous_j,k);
                          BginTime(j2,k)=Mspan(Previous_j,k);
                          BginTime(j3,k)=Mspan(Previous_j,k);
                     else
                           BginTime(j1,k)=temp;
                           BginTime(j2,k)=temp;
                           BginTime(j3,k)=temp;
                     end
    
                     temp_2 = max([PTime(j1,k),PTime(j2,k),PTime(j3,k)]);
                     Mspan(j1,k) = temp_2 + BginTime(j1,k);
                     Mspan(j2,k) = temp_2 + BginTime(j2,k);
                     Mspan(j3,k) = temp_2 + BginTime(j3,k);
    
    
    
    
                 end
                  D(j1,k)=fix(Mspan(j1,k)/24);
                  D(j2,k)=fix(Mspan(j2,k)/24);
                  D(j3,k)=fix(Mspan(j3,k)/24);
    
                     if Mspan(j1,k)>(24*D+10+4) %Hw=10
                        Mspan(j1,k)=24*D(j1,k)+24+temp_2; 
                        BginTime(j1,k)=24*D(j1,k)+24; %养护阶段工序不可中断，第二天才开始工作，开始时间进行修正
                        Mspan(j2,k)=24*D(j2,k)+24+temp_2; 
                        BginTime(j2,k)=24*D(j2,k)+24;
                        Mspan(j3,k)=24*D(j3,k)+24+temp_2; 
                        BginTime(j3,k)=24*D(j3,k)+24;
                     end
             end

         if PNumber ~= 3*a

           if (PNumber-3*a) == 1
              j = Scheme(k,PNumber);
              Previous_j=Scheme(k,PNumber-1);
              

              if Mspan(Previous_j,k)>Mspan(j,k-1)
                          BginTime(j,k)=Mspan(Previous_j,k);
                          
              else
                          BginTime(j,k)=Mspan(j,k-1);
                           
              end
    
                     
              Mspan(j,k) =PTime(j,k) + BginTime(j,k);
              D(j,k)=fix(Mspan(j,k)/24);
                    
                     
    
              if Mspan(j,k)>(24*D+10+4) %Hw=10
                    Mspan(j,k)=24*D(j,k)+24+PTime(j,k); 
                    BginTime(j,k)=24*D(j,k)+24; %养护阶段工序不可中断，第二天才开始工作，开始时间进行修正
                        
              end
           else
                     j1 = Scheme(k,PNumber);
                     j2 = Scheme(k,PNumber-1);
                     
                     temp = max([Mspan(j1,k-1),Mspan(j2,k-1)]);
                     Previous_j=Scheme(k,PNumber-2);
                     if Mspan(Previous_j,k)>temp
                          BginTime(j1,k)=Mspan(Previous_j,k);
                          BginTime(j2,k)=Mspan(Previous_j,k);
                          
                     else
                           BginTime(j1,k)=temp;
                           BginTime(j2,k)=temp;
                           
                     end
    
                     temp_2 = max([PTime(j1,k),PTime(j2,k)]);
                     Mspan(j1,k) = temp_2 + BginTime(j1,k);
                     Mspan(j2,k) = temp_2 + BginTime(j2,k);
                     D(j1,k)=fix(Mspan(j1,k)/24);
                     D(j2,k)=fix(Mspan(j2,k)/24);
                    
    
                     if Mspan(j1,k)>(24*D+10+4) %Hw=10
                        Mspan(j1,k)=24*D(j1,k)+24+temp_2; 
                        BginTime(j1,k)=24*D(j1,k)+24; %养护阶段工序不可中断，第二天才开始工作，开始时间进行修正
                        Mspan(j2,k)=24*D(j2,k)+24+temp_2; 
                        BginTime(j2,k)=24*D(j2,k)+24;
                      
                     end

           end

         end
        
    
    %%%%%%%%%%%%%%%%%%%%第2,3,6,7道工序的完成时间
      otherwise
          for i=1:PNumber
                if i==1     
                 j=Scheme(k,1);
                 BginTime(j,k)=Mspan(j,k-1);
                else
                 j=Scheme(k,i); %当前工件，Scheme是染色体生产的调度工序
                 Previous_j=Scheme(k,i-1); %该工序中的前一个工件
                       if Mspan(Previous_j,k)>Mspan(j,k-1)
                          BginTime(j,k)=Mspan(Previous_j,k);
                       else
                           BginTime(j,k)=Mspan(j,k-1);
                       end
                end
            Mspan(j,k)=BginTime(j,k)+PTime(j,k);
            D=fix(Mspan(j,k)/24);
                if Mspan(j,k)>(24*D+10) %Hw=10
                  Mspan(j,k)=Mspan(j,k)+14; %HN=14
                end
         end
 
  end
end

%%%%%%%%%%%%%%%%%%%编写目标函数,即所有工件交付的总费用 TCost（延迟和提前）。
CMspan=Mspan(:,MNumber);%%%%提取最后一列，即每个工件最后一道工序的完成时间
TCost=0;

for j=1:PNumber
    temp1=CMspan(j,1)-Ddate(j);%%%延迟的时间
    temp2=Ddate(j)-CMspan(j,1);%%%提前的时间
    if temp1>=0
        Cost(j)=10*temp1;%%%延迟的费用，10系数
    elseif temp2>=0
        Cost(j)=2*temp2;  %%%提前的费用，2系数
    else
        Cost(j)=0;
    end
    TCost=TCost+ Cost(j);
end
